pull: Add OSTREE_REPO_PULL_FLAGS_UNTRUSTED flag
authorAlexander Larsson <alexl@redhat.com>
Wed, 23 Mar 2016 10:47:44 +0000 (11:47 +0100)
committerColin Walters (automation) <walters+githubbot@verbum.org>
Fri, 25 Mar 2016 12:56:55 +0000 (12:56 +0000)
If this is set we verify all objects we pull, even for local remotes,
and we avoid hard-linking into local source repos.

https://bugzilla.gnome.org/show_bug.cgi?id=764125

Closes: #221
Approved by: cgwalters

apidoc/ostree-sections.txt
src/libostree/libostree.sym
src/libostree/ostree-repo-pull.c
src/libostree/ostree-repo.c
src/libostree/ostree-repo.h

index 87c138d877e71b8f494da3f7391a2c5a49e85b5d..1eef5da7bde6b50e25a7bdcff1af2fde6cb4c2c7 100644 (file)
@@ -269,6 +269,7 @@ ostree_repo_load_file
 ostree_repo_load_object_stream
 ostree_repo_query_object_storage_size
 ostree_repo_import_object_from
+ostree_repo_import_object_from_with_trust
 ostree_repo_delete_object
 OstreeRepoCommitFilterResult
 OstreeRepoCommitFilter
index 7f10b75dcf26e048ea765b2b54ebe4e63131a3d2..47015e14f3f953248eb93a7b970202bf3df3f985 100644 (file)
@@ -328,8 +328,7 @@ global:
  *                         NOTE NOTE NOTE
  */
 
-/* UNCOMMENT WITH NEW SYMBOLS HERE:
 LIBOSTREE_2016.5 {
 global:
+        ostree_repo_import_object_from_with_trust;
 } LIBOSTREE_2016.4;
-*/
index ecbd73860c2112d7ec616ae5d985497ab7cd1309..26284806426b925f3c547c6466a24892f2060ba1 100644 (file)
@@ -93,6 +93,7 @@ typedef struct {
 
   gboolean          is_mirror;
   gboolean          is_commit_only;
+  gboolean          is_untrusted;
 
   char         *dir;
   gboolean      commitpartial_exists;
@@ -473,9 +474,9 @@ scan_dirtree_object (OtPullData   *pull_data,
 
       if (!file_is_stored && pull_data->remote_repo_local)
         {
-          if (!ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local,
-                                               OSTREE_OBJECT_TYPE_FILE, file_checksum,
-                                               cancellable, error))
+          if (!ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
+                                                          OSTREE_OBJECT_TYPE_FILE, file_checksum, !pull_data->is_untrusted,
+                                                          cancellable, error))
             goto out;
         }
       else if (!file_is_stored && !g_hash_table_lookup (pull_data->requested_content, file_checksum))
@@ -1189,9 +1190,9 @@ scan_one_metadata_object_c (OtPullData         *pull_data,
   if (pull_data->remote_repo_local)
     {
       if (!is_stored &&
-          !ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local,
-                                           objtype, tmp_checksum,
-                                           cancellable, error))
+          !ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
+                                                      objtype, tmp_checksum, !pull_data->is_untrusted,
+                                                      cancellable, error))
         goto out;
       is_stored = TRUE;
       is_requested = TRUE;
@@ -1931,6 +1932,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
 
   pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0;
   pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0;
+  pull_data->is_untrusted = (flags & OSTREE_REPO_PULL_FLAGS_UNTRUSTED) > 0;
 
   if (error)
     pull_data->async_error = &pull_data->cached_async_error;
index 09791c6a356e71be014c12472888cea18bd9275d..a5d0bb2d3f14988ad12a839cf986ac48d7d40f77 100644 (file)
@@ -3310,24 +3310,37 @@ import_one_object_copy (OstreeRepo    *self,
                         OstreeRepo    *source,
                         const char   *checksum,
                         OstreeObjectType objtype,
+                        gboolean      trusted,
                         GCancellable  *cancellable,
                         GError        **error)
 {
   gboolean ret = FALSE;
   guint64 length;
-  g_autoptr(GInputStream) object = NULL;
+  g_autoptr(GInputStream) object_stream = NULL;
 
   if (!ostree_repo_load_object_stream (source, objtype, checksum,
-                                       &object, &length,
+                                       &object_stream, &length,
                                        cancellable, error))
     goto out;
 
   if (objtype == OSTREE_OBJECT_TYPE_FILE)
     {
-      if (!ostree_repo_write_content_trusted (self, checksum,
-                                              object, length,
-                                              cancellable, error))
-        goto out;
+      if (trusted)
+        {
+          if (!ostree_repo_write_content_trusted (self, checksum,
+                                                  object_stream, length,
+                                                  cancellable, error))
+            goto out;
+        }
+      else
+        {
+          g_autofree guchar *real_csum = NULL;
+          if (!ostree_repo_write_content (self, checksum,
+                                          object_stream, length,
+                                          &real_csum,
+                                          cancellable, error))
+            goto out;
+        }
     }
   else
     {
@@ -3336,10 +3349,29 @@ import_one_object_copy (OstreeRepo    *self,
           if (!copy_detached_metadata (self, source, checksum, cancellable, error))
             goto out;
         }
-      if (!ostree_repo_write_metadata_stream_trusted (self, objtype,
-                                                      checksum, object, length,
-                                                      cancellable, error))
-        goto out;
+
+      if (trusted)
+        {
+          if (!ostree_repo_write_metadata_stream_trusted (self, objtype,
+                                                          checksum, object_stream, length,
+                                                          cancellable, error))
+            goto out;
+        }
+      else
+        {
+          g_autofree guchar *real_csum = NULL;
+          g_autoptr(GVariant) variant = NULL;
+
+          if (!ostree_repo_load_variant (source, objtype, checksum,
+                                         &variant, error))
+            goto out;
+
+          if (!ostree_repo_write_metadata (self, objtype,
+                                           checksum, variant,
+                                           &real_csum,
+                                           cancellable, error))
+            goto out;
+        }
     }
 
   ret = TRUE;
@@ -3419,11 +3451,43 @@ ostree_repo_import_object_from (OstreeRepo           *self,
                                 const char           *checksum, 
                                 GCancellable         *cancellable,
                                 GError              **error)
+{
+  return
+    ostree_repo_import_object_from_with_trust (self, source, objtype,
+                                               checksum, TRUE, cancellable, error);
+}
+
+/**
+ * ostree_repo_import_object_from_with_trust:
+ * @self: Destination repo
+ * @source: Source repo
+ * @objtype: Object type
+ * @checksum: checksum
+ * @trusted: If %TRUE, assume the source repo is valid and trusted
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Copy object named by @objtype and @checksum into @self from the
+ * source repository @source.  If both repositories are of the same
+ * type and on the same filesystem, this will simply be a fast Unix
+ * hard link operation.
+ *
+ * Otherwise, a copy will be performed.
+ */
+gboolean
+ostree_repo_import_object_from_with_trust (OstreeRepo           *self,
+                                           OstreeRepo           *source,
+                                           OstreeObjectType      objtype,
+                                           const char           *checksum,
+                                           gboolean              trusted,
+                                           GCancellable         *cancellable,
+                                           GError              **error)
 {
   gboolean ret = FALSE;
   gboolean hardlink_was_supported = FALSE;
-      
-  if (self->mode == source->mode)
+
+  if (trusted && /* Don't hardlink into untrusted remotes */
+      self->mode == source->mode)
     {
       if (!import_one_object_link (self, source, checksum, objtype,
                                    &hardlink_was_supported,
@@ -3438,10 +3502,10 @@ ostree_repo_import_object_from (OstreeRepo           *self,
       if (!ostree_repo_has_object (self, objtype, checksum, &has_object,
                                    cancellable, error))
         goto out;
-  
+
       if (!has_object)
         {
-          if (!import_one_object_copy (self, source, checksum, objtype,
+          if (!import_one_object_copy (self, source, checksum, objtype, trusted,
                                        cancellable, error))
             goto out;
         }
@@ -3452,6 +3516,7 @@ ostree_repo_import_object_from (OstreeRepo           *self,
   return ret;
 }
 
+
 /**
  * ostree_repo_query_object_storage_size:
  * @self: Repo
index 07e76aa8d14e0d068647a78a3cebb7c350cb52e4..f83aef23d81285bb2c3b8fc57922f0bb29950492 100644 (file)
@@ -423,6 +423,14 @@ gboolean      ostree_repo_import_object_from (OstreeRepo           *self,
                                               const char           *checksum,
                                               GCancellable         *cancellable,
                                               GError              **error);
+_OSTREE_PUBLIC
+gboolean      ostree_repo_import_object_from_with_trust (OstreeRepo           *self,
+                                                         OstreeRepo           *source,
+                                                         OstreeObjectType      objtype,
+                                                         const char           *checksum,
+                                                         gboolean              trusted,
+                                                         GCancellable         *cancellable,
+                                                         GError              **error);
 
 _OSTREE_PUBLIC
 gboolean      ostree_repo_delete_object (OstreeRepo           *self,
@@ -891,11 +899,13 @@ gboolean ostree_repo_prune (OstreeRepo        *self,
  * @OSTREE_REPO_PULL_FLAGS_NONE: No special options for pull
  * @OSTREE_REPO_PULL_FLAGS_MIRROR: Write out refs suitable for mirrors
  * @OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY: Fetch only the commit metadata
+ * @OSTREE_REPO_PULL_FLAGS_UNTRUSTED: Don't trust local remote
  */
 typedef enum {
   OSTREE_REPO_PULL_FLAGS_NONE,
   OSTREE_REPO_PULL_FLAGS_MIRROR = (1 << 0),
-  OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1)
+  OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1),
+  OSTREE_REPO_PULL_FLAGS_UNTRUSTED = (1 << 2)
 } OstreeRepoPullFlags;
 
 _OSTREE_PUBLIC